home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-04-13 | 12.9 KB | 392 lines | [TEXT/EDIT] |
- ;-------------------------------------------------------------------------------;
- ; ;
- ; SpeechGlue - Interface for PASCAL programs using the ;
- ; Macintalk speech driver. ;
- ; ;
- ; Copyright 1984, Joseph Katz / Mark Barton. Not to be copied or ;
- ; distributed without the express written permission of the authors. ;
- ; ;
- ; Modification History: ;
- ; 06/02/85 - Modified only minutes before shipment of software ;
- ; supplement. Modified to separate code and data ;
- ; segments. This was done in a vast hurry. There ;
- ; are no known bugs in it, but it was not done cleanly. ;
- ; ;
- ; ;
- ;-------------------------------------------------------------------------------;
-
- .NOLIST
- .INCLUDE TLASM/SYSEQU.TEXT
- .INCLUDE TLASM/SYSTRAPS.TEXT
- .INCLUDE TLASM/SYSERR.TEXT
- .INCLUDE TLASM/TOOLTRAPS.TEXT
- .INCLUDE TLASM/TOOLEQU.TEXT
- .LIST
-
-
- RdrHandle .EQU 52 ;PBLOCK OFFSET OF HANDLE TO READER CODE
- RulesFN .EQU 60 ;OFFSET TO READER EXCEPTIONS FILENAME POINTER
-
- IDPitchMode .EQU 0
- IDRate .EQU 2 ;ID=1 IS USED FOR KILLIO
- IDSex .EQU 3 ;RESERVED FOR FUTURE IMPLEMENTATION
- IDBaseline .EQU 4
-
- fullUnitT .EQU -4000 ;ERROR CODE FOR DRIVER TABLE FULL
-
- Pblock .EQU 0 ;OFFSET TO IOPARMBLOCK
- ReaderHandle .EQU 66 ;OFFSET TO READER HANDLE
- SpeechRfNum .EQU 70 ;OFFSET TO SPEECH DRIVER REFERENCE NUMBER
- TalkRefNum .EQU 74 ;OFFSET TO TALK PACKAGE REFNUM
-
-
- ; FUNCTION SpeechOn(EXCPFile: Str255; VAR SpeechHandle: SpeechRecord): SpeechErr;
-
- ; Open speech driver. This is complicated by the need to arbitrate the
- ; driver unit number, which must be done prior to the actual device open.
-
- .FUNC SpeechOn,1
-
- MOVE.L A2,-(SP) ;SAVE A2 ON STACK
-
- ; Try to allocate driver globals area
- MOVE.L #100,D0 ;GRAB 100 BYTES
- _NewHandle
- MOVE.L 8(SP),A1 ;GET SPEECH RECORD ADDR
- MOVE.L A0,(A1) ;SAVE GLOBALS HANDLE
- TST.W D0
- BNE.S ONERROR ;IF ERROR, JUST RETURN
- _HLock ;LOCK HANDLE
- MOVE.L (A0),A2 ;SAVE POINTER TO GLOBALS
-
- ; Clear parm block
- MOVEQ #0,D0
- MOVEQ #24,D1
- MOVE.L A2,A0
- CLOOP MOVE.L D0,(A0)+
- DBF D1,CLOOP
-
- ; Open MacinTalk resource file
-
- CLR.W -(SP) ;SPACE FOR RETURN CODE
- PEA DriverID ;NAME OF RESOURCE FILE
- _OpenResFile ;OPEN IT
- MOVE.W (SP)+,D0 ;GET RESOURCE FILE ID
- BPL.S GOTRESFILE ;GOOD RETURN, BRANCH
- MOVE.W ResErr,D0 ;SET RETURN CODE
-
- ONERROR MOVE.L (SP)+,A2 ;RESTORE A2
- MOVE.L (SP),8(SP) ;MOVE RETURN ADDR
- ADDQ.L #8,SP ;FIX STACK
- MOVE.W D0,4(SP) ;SET RETURN CODE
- RTS ;AND GO AWAY
-
- GOTRESFILE MOVE.W D0,TalkRefNum(A2) ;SAVE FILE REFNUM FOR LATER
-
-
- ; Set ResPreLoad to FALSE
-
- MOVE.B #0,-(SP)
- _SetResLoad
-
-
- ; Get handle to synthesizer resource; TYPE = DRVR, NAME=MacinTalk
-
- CLR.L -(SP) ;SPACE FOR RETURN CODE
- MOVE.L #'DRVR',-(SP) ;RESOURCE TYPE
- PEA SpeechName ;RESOURCE NAME
- _GetNamedResource ;GET DRIVER RESOURCE
- MOVE.L (SP)+,A1 ;GET HANDLE TO RESOURCE (*** WAS AFTER BNE)
- MOVE.W ResErr,D0 ;GOOD RETURN?
- BNE.S ONERROR ;NO, BRANCH TO ERROR RETURN
-
-
- ; Restore ResPreLoad to TRUE
-
- MOVE.B #1,-(SP)
- _SetResLoad
-
-
- ; Find an empty slot in driver unit table (looking backwards from end)
-
- MOVE.L uTableBase,A0 ;GET DRIVER UNIT TABLE BASE
- ADDA.W #128,A0 ;START AT END+4 OF UNIT TABLE
- MOVE.W #32,D0 ;LAST UNIT IN TABLE IS #31
-
- @3 SUBQ.W #1,D0 ;REDUCE SLOT NUMBER
- CMP.W #18,D0 ;NO FREE SLOTS BELOW UNIT 18
- BGT.S @4
- MOVE.W #fullUnitT,D0 ;SETUP ERROR CODE
- BRA.S ONERROR ;AND GO AWAY
-
- @4 CMPI.L #0,-(A0) ;IS SLOT EMPTY?
- BNE.S @3 ;NO, KEEP LOOPING
-
-
- ; Change resource ID to new driver number, and load in resource data
-
- MOVE.W D0,D1 ;DRIVER NUMBER
- ADDQ.W #1,D1 ;
- NEG.W D1 ;REF NUMBER
- MOVE.W D1,SpeechRfNum(A2) ;SAVE REFERENCE NUMBER
-
- MOVE.L A1,-(SP) ;RESOURCE HANDLE
- MOVE.W D0,-(SP) ;NEW DRIVER NUMBER
- MOVE.L #0,-(SP) ;DON'T CHANGE THE RESOURCE NAME
- _SetResInfo
-
-
- MOVE.L A1,-(SP)
- _LoadResource
- MOVE.W resErr,D0 ;FOR DEBUGGING
-
-
- MOVE.L A1,A0 ;TRANSFER HANDLE TO A0
- _HLock ;LOCK DRIVER CODE DOWN
-
-
- ; Get SpeechOn input parms from stack
-
- MOVE.L (SP)+,A2 ;RESTORE A2
- MOVE.L (SP)+,A0 ;GET RETURN ADDRESS
- MOVE.L (SP)+,D0 ;GET ADDR OF SPEECHREC HANDLE
- MOVE.L (SP)+,A1 ;GET EXCPS FILENAME PTR
- MOVE.L A0,-(SP) ;RESTORE RETURN ADDR
-
- MOVE.L A2,-(SP) ;SAVE A2
- MOVE.L D0,A2 ;ADDR OF DEV GLOBALS HANDLE
- MOVE.L (A2),A2 ;DEVICE GLOBALS HANDLE
- MOVE.L A2,-(SP) ;SAVE DEVICE GLOBALS HANDLE
- MOVE.L (A2),A2 ;DEREF TO POINTER
-
- ; Build parm block and open the driver
-
- LEA Pblock(A2),A0 ;A0 --> PARM BLOCK
- MOVE.L A1,RulesFN(A0) ;SAVE PTR TO EXCPS FILENAME IN PBLOCK
- LEA SpeechName,A1 ;A1 --> DRIVER NAME
- MOVE.L A1,IOFileName(A0) ;STORE DRIVER NAME IN PARM BLOCK
- CLR.W IODrvNum(A0) ;USE DEFAULT DRIVE
- CLR.W IOFileType(A0) ;CLEAR TYPE/PERMISSIONS
- CLR.L IOOwnBuf(A0) ;USE SYSTEM BUFFER
-
- _Open
- MOVE.W IOResult(A0),12(SP) ;SAVE RETURN CODE FROM OPEN
- MOVE.L RdrHandle(A0),ReaderHandle(A2) ;SAVE HANDLE TO READER CODE
-
- MOVE.L (SP)+,A0 ;UNLOCK DEVICE GLOBALS
- _HUnlock
-
- MOVE.L (SP)+,A2 ;RESTORE A2
- RTS
-
-
- SpeechName .BYTE 7
- .ASCII '.SPEECH'
- DriverID .BYTE 9
- .ASCII 'MacinTalk'
-
-
-
-
- ; PROCEDURE SpeechOff(SpeechHandle: SpeechRecord);
-
- ; Closes speech driver.
-
- .PROC SpeechOff
-
- MOVE.L A2,-(SP) ;SAVE A2
- MOVE.L 8(SP),A0 ;GET DEVICE GLOBALS HANDLE
- _HLock
- MOVE.L (A0),A2 ;DEREFERENCE TO POINTER
-
- LEA Pblock(A2),A0 ;POINTER TO PARM BLOCK
- _Close ,IMMED
-
- MOVE.W TalkRefNum(A2),D0 ;MacinTalk REFNUM
- BEQ.S @1 ;DONT CLOSE SYSTEM RES FILE
- MOVE.W D0,-(SP)
- _CloseResFile ;BYE-BYE
-
- @1 MOVE.L 8(SP),A0 ;GET DEVICE GLOBALS HANDLE
- _HUnlock ;UNLOCK IT
- _DisposHandle ;TOSS IT
- MOVE.L (SP)+,A2 ;RESTORE A2
- MOVE.L (SP),4(SP) ;FIXUP STACK AND RETURN
- ADDQ.L #4,SP
- RTS
-
-
- ; PROCEDURE SpeechRate(SpeechHandle: SpeechRecord; Rate: Integer);
-
- ; Set the speaking rate in words/minute. Range and validity
- ; checking is done in SpeechPrime.
-
- .PROC SpeechRate
-
- MOVE.L (SP)+,D1 ;GET RETURN ADDR
- MOVE.W (SP)+,D2 ;GET RATE PARM
- MOVE.L (SP)+,A0 ;GET DEVICE GLOBALS
- MOVE.L D1,-(SP) ;RESTORE RETURN ADDR
-
- MOVE.L A0,-(SP) ;SAVE DEVICE GLOBALS HANDLE
- _HLock ;LOCK IT
- MOVE.L (A0),A1 ;DEREF GLOBALS HANDLE
-
- LINK A6,#-32 ;CREATE PARM BLOCK ON STACK
- LEA -32(A6),A0 ;POINT A0 AT PARM BLOCK
-
- MOVE.W SpeechRfNum(A1),IORefNum(A0) ;SET SPEECH REFNUM
- MOVE.W #IDRate,CSCode(A0) ;SET RATE PARM ID
- MOVE.W D2,CSParam(A0) ;STORE RATE PARM
-
- _Control ,IMMED
-
- UNLK A6 ;REMOVE DCE FROM STACK
-
- MOVE.L (SP)+,A0 ;RESTORE DEVICE GLOBALS
- _HUnlock ;UNLOCK IT
-
- RTS
-
-
-
- ; PROCEDURE SpeechSex(SpeechHandle: SpeechRecord; SpeakerSex: Sex);
-
- ; Set the speaking sex as Male or Female.
-
- .PROC SpeechSex
-
- MOVEQ #0,D2 ;CLEAR
- MOVE.L (SP)+,D1 ;GET RETURN ADDR
- MOVE.B (SP)+,D2 ;GET SEX PARM (NOTE .B ON MOVE)
- MOVE.L (SP)+,A0 ;GET DEVICE GLOBALS
- MOVE.L D1,-(SP) ;RESTORE RETURN ADDR
-
- MOVE.L A0,-(SP) ;SAVE GLOBALS ON STACK
- _HLock ;LOCK DEVICE GLOBALS
- MOVE.L (A0),A1 ;DEREFERENCE TO POINTER
-
- LINK A6,#-32 ;CREATE PARM BLOCK ON STACK
- LEA -32(A6),A0 ;POINT A0 AT PARM BLOCK
- MOVE.W SpeechRfNum(A1),IORefNum(A0) ;SET SPEECH REFNUM
- MOVE.W #IDSex,CSCode(A0) ;SET SEX PARM ID
- MOVE.W D2,CSParam(A0) ;STORE SEX PARM
-
- _Control ,IMMED
-
- UNLK A6 ;REMOVE PARM BLOCK FROM STACK
-
- MOVE.L (SP)+,A0 ;RESTORE GLOBALS HANDLE
- _HUnlock ;UNLOCK HANDLE
-
- RTS
-
-
-
- ; PROCEDURE SpeechPitch(SpeechHandle: SpeechRecord; Pitch: Integer; Mode: F0Mode);
-
- ; Sets the baseline pitch and the F0 mode. All parameter
- ; validity and range checking is done in SpeechPrime routines.
-
- .PROC SpeechPitch
-
- MOVEQ #0,D2 ;CLEAR THE BUGGER
- MOVE.L (SP)+,A1 ;GET RETURN ADDR
- MOVE.B (SP)+,D2 ;GET PITCH MODE
- MOVE.W (SP)+,D1 ;GET BASELINE PITCH
- MOVE.L (SP)+,A0 ;GET DEVICE GLOBALS HANDLE
- MOVE.L A1,-(SP) ;RESTORE RETURN ADDR
-
- MOVE.L A0,-(SP) ;SAVE GLOBALS ON STACK
- _HLock ;LOCK GLOBALS
- MOVE.L (A0),A1 ;DEREFERENCE
-
- LINK A6,#-32 ;CREATE ROOM FOR PARM BLOCK
- LEA -32(A6),A0
- MOVE.W SpeechRfNum(A1),IORefNum(A0)
-
- MOVE.W #IDPitchMode,CSCode(A0) ;SET MODE ID
- MOVE.W D2,CSParam(A0) ;SET PITCH MODE
- _Control ,IMMED
-
- MOVE.W #IDBaseline,CSCode(A0) ;SET BASELINE ID
- MOVE.W D1,CSPARAM(A0) ;SET BASELINE PITCH
- _Control ,IMMED
-
- UNLK A6
-
- MOVE.L (SP)+,A0 ;RESTORE GLOBALS HANDLE
- _HUnlock ;UNLOCK HANDLE
-
- RTS
-
-
-
- ; FUNCTION MacinTalk(SpeechHandle: SpeechRecord; phonemes: Handle): SpeechErr;
-
- ; Macintalk glue passes phonemes handle to speech driver
- ; write routine.
-
- .FUNC MacinTalk
-
- MOVE.L (SP)+,D0 ;GET RETURN ADDR
- MOVE.L (SP)+,A1 ;GET INPUT HANDLE
- MOVE.L (SP)+,A0 ;GET DEVICE GLOBALS HANDLE
- MOVE.L D0,-(SP) ;RESTORE RETURN ADDR
-
- MOVE.L A0,-(SP) ;SAVE ON STACK
- _HLock ;LOCK GLOBALS HANDLE
-
- MOVE.L A1,A0 ;COPY INPUT HANDLE TO A0
- _GetHandleSize ;GET INPUT HANDLE SIZE IN D0
-
- MOVE.L A2,-(SP)
- MOVE.L 4(SP),A2
- MOVE.L (A2),A2
-
- LEA Pblock(A2),A0 ;POINT A0 TO PARM BLOCK
- MOVE.W SpeechRfNum(A2),IORefNum(A0) ;STORE REF NUM
- MOVE.L A1,IOBuffer(A0) ;STORE INPUT HANDLE
- MOVE.L D0,IOByteCount(A0) ;STORE INPUT HANDLE LENGTH
-
- _Write ,IMMED ;GO TO IT
-
- MOVE.L (SP)+,A2 ;RESTORE A2
- MOVE.L (SP)+,A0 ;RESTORE DEVICE GLOBALS HANDLE
- MOVE.W D0,-(SP) ;SAVE WRITE RETURN CODE
- _HUnlock ;UNLOCK GLOBALS
- MOVE.W (SP)+,D0 ;RESTORE WRITE RETURN CODE
-
- MOVE.W D0,4(SP) ;PUT RETURN CODE ON STACK
- RTS
-
-
-
- ; FUNCTION Reader(theSpeech: SpeechHandle;
- ; English: Pointer;
- ; EnglishLen: LongInt;
- ; Output: Handle): Integer;
-
-
- .FUNC Reader,2 ;READER GLUE
-
- MOVE.L 16(SP),A0 ;GET DEVICE GLOBALS HANDLE
- MOVE.L 12(SP),16(SP)
- MOVE.L 8(SP),12(SP)
- MOVE.L 4(SP),8(SP)
- MOVE.L (SP),4(SP)
- ADDQ.L #4,SP
-
- _HLock
- MOVE.L (A0),A0 ;DEREFERENCE GH
- MOVE.L ReaderHandle(A0),A0 ;GET HANDLE TO READER CODE
- _HLock ;LOCK CODE DOWN
-
- MOVE.L (A0),A0 ;GET PTR TO CODE
- JMP (A0) ;GO DO IT
-
- RTS
-
- .END
-
-